#include <stdio.h>      // 标准输入输出
#include "ohos_init.h"  // 用于初始化服务(services)和功能(features)
#include "cmsis_os2.h"  // CMSIS-RTOS API V2

// HAL(硬件抽象层) 接口：IoT硬件设备操作接口-GPIO
// base/iot_hardware/peripheral/interfaces/kits提供了一系列IoT（The Internet of Things）
// 硬件设备操作的接口，包括FLASH,GPIO,I2C,PWM,UART,WATCHDOG等。
// #include "iot_gpio.h"

// 海思SDK接口：IoT硬件设备操作接口-IO
// OpenHarmony1.0之后，1.0.1是一个比较完善的版本。
// OpenHarmony从1.1.0版本开始，到1.1.3版本，IoT接口的变动比较大，功能上比较残缺。
// 有些接口被移除，只能直接调用海思SDK的接口。
// 海思SDK的接口，以hi_开头，如hi_io_set_func(...)。
// 目前来说，OpenHarmony在轻量级设备这块，尤其是外设接口，支持的不是很好。
// 官方以后主推HDF接口，形式上和1.0的接口比较接近。
// 在2.x和3.0阶段，官方对轻量级设备投入的精力比较少。
// 到目前(2021-12-31)为止，HDF还没有一个轻量级芯片支持，包括Hi3861。
#include "hi_io.h"
#include "hi_gpio.h"

#define LED_GPIO HI_IO_NAME_GPIO_7
#define KEY_GPIO HI_IO_NAME_GPIO_5

// 安装中断处理函数
void keyPressedFunc(void *arg)
{
    /*
        静态局部变量：
        使用 static 声明的局部变量在程序运行期间一直存在（即它的生命周期是整个程序运行期间），但它仍然只能在声明它的函数内部访问（即作用域不变）。
        此外，静态局部变量只会被初始化一次，之后的函数调用会保留上次的值。
    */ 
    static hi_gpio_value led_val = HI_GPIO_VALUE1;
    (void)arg;
    printf("key pressed \n");
    printf("led_val %d \n",led_val);
    // 设置LED的电平
    hi_gpio_set_ouput_val(LED_GPIO,led_val);
    led_val = !led_val;

    return ;
}

void led_init(void)
{
    // 初始化GPIO
    // hi_io.h 包中的接口
    hi_gpio_init();

    // 设置gpio下拉模式 (默认低电平灭)
    // hi_io_set_pull(LED_GPIO,HI_IO_PULL_DOWN);

    // 设置io引脚为通用IO (因为芯片引脚少 功能多 所以先设置该引脚是干什么作用的)
    hi_io_set_func(LED_GPIO,HI_IO_FUNC_GPIO_7_GPIO);

    // 设置GPIO为输出
    hi_gpio_set_dir(LED_GPIO,HI_GPIO_DIR_OUT);

    return ;
}

void key_init(void)
{
    // 初始化GPIO
    hi_gpio_init();

    // 设置io引脚为通用IO (因为芯片引脚少 功能多 所以先设置该引脚是干什么作用的)
    hi_io_set_func(KEY_GPIO,HI_IO_FUNC_GPIO_5_GPIO);

    // 设置gpio上拉（默认高电平）
    // hi_io_set_pull(KEY_GPIO,HI_IO_PULL_UP);

    // 设置GPIO为输入
    hi_gpio_set_dir(KEY_GPIO,HI_GPIO_DIR_IN);

    // 注册GPIO中断处理函数
    hi_gpio_register_isr_function(KEY_GPIO,   /* GPIO引脚 */
        HI_INT_TYPE_EDGE,                     /* 边沿触发 */
        HI_GPIO_EDGE_FALL_LEVEL_LOW,          /* 下降沿触发 */
        keyPressedFunc,                       /* 中断处理函数 */
        NULL
    );

    return;
}

static void led_task(void *arg)
{
    (void)arg;

    led_init();
    key_init();

    return;
}

static void led_switch(void)
{
    osThreadAttr_t attr;               // 定义一个线程属性

    attr.name = "LedTask";             // 设置任务名
    attr.stack_size = 1024;            // 设置线程任务栈空间大小
    attr.priority = osPriorityNormal;  // 设置线程优先级

    // 创建线程（到内核API详述）
    // 1.0 CMSIS-RTOS2 API：third_party\cmsis\CMSIS\RTOS2\Include\cmsis_os2.h
    // 1.1.3 kernel\liteos_m\kal\cmsis\cmsis_liteos2.c
    // RTOS: real-time operating system
    // CMSIS: Cortex Microcontroller Software Interface Standard
    if (osThreadNew(led_task, NULL, &attr) == NULL)
    {
        printf("[led_switch] Create LedTask failed!\n");
    }
}

// ohos_init.h 中定义的宏，让函数在系统启动时执行
SYS_RUN(led_switch);
